home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…stman Always Clicks Twice / ADC Developer CD (1993-01) (''The Postman Always Clicks Twice'')_iso / Dev.CD 199301.iso / Tools & Apps / Networking & Communications / Network Watch (DMZ) 1.0 / dMZAT.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-17  |  27.2 KB  |  1,167 lines  |  [TEXT/KAHL]

  1. /*
  2. #-------------------------------------------------------------------------------------------
  3. #
  4. #    Program:    < DMZ 1.1 >
  5. #    File:        < dmzAT.c >
  6. #    
  7. #    by Pete Helme
  8. #    of <Apple Macintosh Developer Technical Support - or wheverever>
  9. #    modified by Rich Kubota
  10. #    3/25/92    rrk    Fixed program so that if no zones are selected and the "no zones (*)"
  11. #                item selected, the local zone is searched.
  12. #    3/25/92    rrk Implemented J. Luther's socket listener, replacing Pete's listener
  13. #    3/25/92 rrk Updated code to work with Think C 5.0.
  14. #
  15. #    Copyright © 1990 Apple Computer, Inc.
  16. #    All rights reserved.
  17. #    
  18. #-------------------------------------------------------------------------------------------
  19. */
  20.  
  21. /*
  22.  *     dmz Sample AppleTalk Stuff
  23.  *
  24.  *    This unit handles all AppleTalk functions for dmz.  Including: AppleTalk 
  25.  *    presence verification and activation, socket opening, set self send enabling  
  26.  *    name binding protocol registration, bridge presence verification, 
  27.  *    zone name lookups, hot dish zapper, name removal, socket closing & no weeds.
  28.  *
  29.  */
  30.  
  31. #ifndef THINK_C
  32. #include    <types.h>
  33. #include    <quickdraw.h>
  34. #include    <toolutils.h>
  35. #include    <fonts.h>
  36. #include    <events.h>
  37. #include    <windows.h>
  38. #include    <dialogs.h>
  39. #include    <menus.h>
  40. #include    <desk.h>
  41. #include    <textedit.h>
  42. #include    <scrap.h>
  43. #include    <segload.h>
  44. #include    <osevents.h>
  45. #include    <files.h>
  46. #include    <devices.h>
  47. #include    <memory.h>
  48. #include    <appletalk.h>
  49. #include    <lists.h>
  50. #include    <SysEqu.h>
  51. #include    <Script.h>
  52. #include    <Packages.h>
  53. #include    <OSUtils.h>
  54. #include    <CursorCtl.h>
  55. #endif
  56.  
  57. #include    "dmz.h"
  58.         
  59. /*
  60.  *    Socket listener routines found in dmz.a.o
  61.  */
  62. extern pascal OSErr SL_INITSKTLISTENER(QHdrPtr freeQ, QHdrPtr usedQ);
  63. extern void SL_THELISTENER();
  64.  
  65. void doGetZoneListPhs2();
  66.  
  67. /* globals from afar */
  68. /* out main dialog */
  69. extern DialogPtr     gLookupDialog;
  70. extern DialogPtr     gMyDialog;
  71. extern char         gNameGlob[34];
  72. extern SysEnvRec    GMAC;                /* set up by Initialize */
  73.  
  74. /* and others */
  75. Ptr                 gBuffPtr;
  76. myMPPParamBlock     *gPBLkUP;
  77. Boolean             gUpdateListFlag;
  78. Boolean             gLookupFinished;
  79. NamesTableEntry     gMyNTE;
  80. AddrBlock             gTheBridgeAddress;
  81. Boolean                gHasPhase2 = false;
  82. NamesTableEntry     gLookupNTE;    
  83.  
  84. Ptr                    GTHEVBLPTR;
  85. Ptr                    GTHETASKPTR;
  86.  
  87. /*     
  88.  *    Inline routines for saving & restoring A5 in our PLookupName completion routine.
  89.  *
  90.  *    move.l    a5, -(a7)
  91.  *    move.l    $FFFC(a0), a5    ; -4(A0)
  92.  *
  93.  */
  94.  pascal void saveThatA5()
  95.     = {0x2f0d, 0x2a68, 0xFFFC};
  96.     
  97. /*
  98.  *    move.l    (a7)+, a5
  99.  */
  100. pascal void restoreThatA5()
  101.     = {0x2a5f};
  102.     
  103. /*     
  104.  *    Boring Pascal string concat routine.  Skip ahead a bit.
  105.  */
  106. char *Pstrcat(char *s, char *t)
  107. {
  108.     long     i, length;
  109.     char     *p;
  110.     
  111.     length = *t;
  112.     p = s + *s + 1;
  113.     t++;
  114.     
  115.     for(i=0;i<length;i++) 
  116.         *p++ = *t++;
  117.  
  118.     *s += length;
  119.     return s;
  120. }
  121.  
  122. /*     
  123.  *    Returns length of pascal type strings.  Again, quite boring.
  124.  */
  125. unsigned char PStrLen(char *e)
  126. {
  127.     unsigned char length;
  128.     
  129.     length = *e;
  130.     return(length);
  131. }
  132.  
  133. /*
  134.  * Returns true if two Pascal strings are the same, false otherwise.
  135.  */
  136.  
  137. Boolean    PStrComp(char *str1, char *str2)
  138.  
  139. {
  140.     unsigned char    i;
  141.     unsigned char    j;
  142.     Boolean            ok;
  143.     
  144.     if (*str1 != *str2)
  145.         return(false);                    /* strings are of unequal length */
  146.     
  147.     i = *str1;
  148.     ok = true;                            /* assume strings are the same */
  149.     j = 0;
  150.     for (j = 0; j < i; j++) {
  151.         if (*(++str1) != *(++str2))
  152.             return(false);
  153.     }
  154.     return(true);
  155. }        
  156.  
  157. /*     
  158.  *     Removes a specific NBP Lookup from queue if one pending.  Why?  So we don't hurt ourselves.
  159.  *    
  160.  */
  161. void killLookups()
  162. {
  163.     MPPParamBlock     killPB;
  164.     OSErr             resultCode;
  165.  
  166.     if(gPBLkUP->myMPP.MPPioResult == 1) {
  167.         killPB.NBPnKillQEl = (Ptr)&gPBLkUP->myMPP.MPP.qLink;
  168.         resultCode = PKillNBP(&killPB, false);
  169.         }
  170. }
  171.  
  172. /*     
  173.  *    Removes our name and ATP socket.
  174.  */
  175. void removeMyNameAndSocket()
  176. {
  177.     MPPParamBlock     pb;
  178.     OSErr             resultCode;
  179.  
  180.     /* 
  181.      *    pointer to entityName 
  182.      */
  183.     pb.NBPentityPtr = (Ptr)&gMyNTE.nt.entityData[0];
  184.     resultCode = PRemoveName(&pb, false);
  185.     
  186. }
  187.  
  188. /*     
  189.  *    Shutdown our AppleTalk usage.  Disposes of name lookup buffers.  
  190.  *    Calls to remove our NBP name.    
  191.  */
  192. void closeUpOurAppleTalk()
  193. {
  194.     killLookups();
  195.     
  196.     if(gBuffPtr != 0L)
  197.         DisposPtr(gBuffPtr);
  198.     if(gPBLkUP != 0L)
  199.         DisposPtr((Ptr) gPBLkUP);
  200.     removeMyNameAndSocket();
  201. }
  202.     
  203. /*     
  204.  *    Registers name from the System's STR -16096 resource. (what is usually seen in the Chooser) 
  205.  */
  206.  
  207. void registerMyName()
  208. {
  209.     MPPParamBlock     pb;
  210.     OSErr             resultCode;
  211.     long             byteCount;
  212.     StringHandle    userName;
  213.     
  214.     byteCount = 0L;
  215.  
  216.     /* this grabs the name from the user's Chooser name string.  If there is nothing
  217.     there we'll substitute our own name */
  218.     userName = GetString(kMachineNameResourceID); 
  219.     if(**userName == 0)
  220.         BlockMove("\pYour name here.", *userName, 15L);
  221.  
  222.     NBPSetNTE((Ptr)&gMyNTE, *userName, "\pnot anything", "\p*", gMyNTE.nt.nteAddress.aSocket);
  223.  
  224.     pb.NBPinterval = 2;
  225.     pb.NBPcount = 3;
  226.  
  227.     /* wants pointer to NamesTableEntry NOT entityName! */
  228.     pb.NBP.NBPPtrs.ntQElPtr = (Ptr)&gMyNTE;
  229.     pb.NBPverifyFlag = 1; /* verify that we be the only one! */
  230.  
  231.     resultCode = PRegisterName(&pb, false);
  232. }
  233.  
  234.     
  235. /* 
  236.  *    Enables AppleTalk option to talk to one's own node. ONLY for SE's, //'s or MacPluses with AppleTalk driver of v48 or greater!! 
  237.  */
  238. void enableSetSelfSend() 
  239. {
  240.  
  241.     SetSelfparms    pb;
  242.     OSErr             resultCode;
  243.  
  244.     pb.newSelfFlag = true;  /* set self send option */
  245.     resultCode = PSetSelfSend((MPPPBPtr) &pb, false);
  246.     if(resultCode!=noErr)
  247.         SysBeep(1);
  248. }
  249.     
  250.  
  251. /*    
  252.  *    Checks to see if we are running AppleTalk Phase 2 compatible drivers.
  253.  */
  254. void phase2Check()
  255. {
  256.     if(GMAC.atDrvrVersNum >= 53) 
  257.         gHasPhase2 = true;
  258.     else 
  259.         HideDItem(gLookupDialog, kPhase2Item);
  260. }
  261.  
  262.  
  263. /*    
  264.  *    Opens up AppleTalk.  Opens our ATP socket.
  265.  */
  266. void InitAppleTalkVars()
  267. {
  268.     extern void     getTheZoneList();
  269.     
  270.     /* 
  271.      *    buffer necessary for async name lookups 
  272.      */
  273.     gPBLkUP = (myMPPParamBlock *) NewPtr(sizeof(myMPPParamBlock));
  274.     gBuffPtr = NewPtr(30000L);
  275.     
  276.     if(gPBLkUP != 0L) {
  277.         if(ATPLoad() == noErr) {
  278.             phase2Check();
  279.             getTheZoneList();
  280.             enableSetSelfSend() ;
  281.             registerMyName();
  282.             }
  283.         else
  284.             ExitToShell();
  285.         }
  286. }
  287.         
  288.  
  289.  
  290. /*
  291.  *    in order for us to use the standard qsort() algorithm, our data must be alligned in
  292.  *    an orderly fashion with a set offset from each data entry. This routine takes care of
  293.  *    that through simple _BlockMove manipulations.
  294.  */
  295. void addToUnpackedBuffer(Ptr oldBuffer, Ptr newBuffer, short numGot, short total)
  296. {
  297.     long    oldIndex = 0L, newIndex = 0L;
  298.     short    i;
  299.     
  300.     for(i=0;i<numGot;i++) {
  301.         BlockMove((Ptr)oldBuffer+oldIndex, (Ptr)newBuffer+(newIndex+total)*33, 33L);
  302.         oldIndex += (char)((Ptr)oldBuffer+oldIndex)[0]+1L;
  303.         newIndex += 1;
  304.         }
  305. }
  306.  
  307.  
  308. /*
  309.  *    return our local zone name the old fasioned way
  310.  */
  311. void getMyZone(char *myZoneBuffer)
  312. {            
  313.     BDSElement         myZoneBDS;
  314.     ATPParamBlock     ZonePB;
  315.     
  316.     myZoneBDS.buffSize = 33;
  317.     myZoneBDS.buffPtr = (Ptr) myZoneBuffer;
  318.     myZoneBDS.dataSize = 0;
  319.     myZoneBDS.userBytes = 0;
  320.  
  321.     ZonePB.ATPatpFlags = 0;
  322.     ZonePB.ATPioCompletion = 0L; 
  323.     ZonePB.ATPuserData = 0;    /* ATP user data */
  324.     ZonePB.ATPaddrBlock = gTheBridgeAddress;
  325.     ZonePB.ATPreqLength = 0;
  326.     ZonePB.ATPreqPointer = 0L;
  327.     ZonePB.ATPbdsPointer = (Ptr)&myZoneBDS;
  328.     ZonePB.ATPnumOfBuffs = 1;
  329.     ZonePB.ATPtimeOutVal = 3;
  330.     ZonePB.ATPretryCount = 3;
  331.  
  332.     /*
  333.      *    make sure to NIL this field out so bottom three bytes are 0
  334.      */
  335.     ZonePB.ATPuserData = 0x07000000;        /* GetLocalZone = 7 */
  336.         
  337.     if(PSendRequest(&ZonePB, false) != noErr)
  338.         myZoneBuffer[0] = 0;
  339. }
  340.  
  341.  
  342. void doGetZoneListPrePh2()
  343. {            
  344.     BDSElement             myZoneBDS;
  345.     ATPParamBlock         ZonePB;
  346.     OSErr                 theResult;
  347.     long                 tempUserData;
  348.     Ptr                 theBufferPtr;
  349.     short                 zIndex, zoneCallType;
  350.     short                 NumZonesGot = 0, totalZones = 0;
  351.     Boolean             DontGetMoreZones;
  352.     extern ListHandle    zonesList;
  353.     Ptr                    returnBuffer;
  354.     
  355.     zIndex = 1;
  356.     zoneCallType = _GetZoneList;
  357.     DontGetMoreZones = false;
  358.     
  359.     returnBuffer = NewPtr(33*300); /* size of maxstring size * 300 zones */
  360.     
  361.     theBufferPtr = NewPtr(578); /* size of BDS */
  362.     if(MemError()==noErr) {
  363.         while(!DontGetMoreZones) {
  364.             zIndex += NumZonesGot;            /* index count. 1 for start */
  365.             myZoneBDS.buffSize = 578;
  366.             myZoneBDS.buffPtr = theBufferPtr;
  367.             myZoneBDS.dataSize = 0;
  368.             myZoneBDS.userBytes = 0;
  369.     
  370.             ZonePB.ATPatpFlags = 0;
  371.             ZonePB.ATPioCompletion = 0L; 
  372.             ZonePB.ATPuserData = 0;    /* ATP user data */
  373.             ZonePB.ATPaddrBlock = gTheBridgeAddress;
  374.             ZonePB.ATPreqLength = 0;
  375.             ZonePB.ATPreqPointer = 0L;
  376.             ZonePB.ATPbdsPointer = (Ptr)&myZoneBDS;
  377.             ZonePB.ATPnumOfBuffs = 1;
  378.             ZonePB.ATPtimeOutVal = 4;
  379.             ZonePB.ATPretryCount = 4;
  380.             
  381.             BlockMove((Ptr) &zoneCallType + 1, (Ptr) &tempUserData, 1L);
  382.             BlockMove((Ptr) &zIndex, (Ptr)&tempUserData + 2, 2L);
  383.     
  384.             ZonePB.ATPuserData = tempUserData;
  385.                 
  386.             theResult = PSendRequest(&ZonePB, false);
  387.     
  388.             if(theResult == noErr) {            
  389.                 tempUserData = myZoneBDS.userBytes;
  390.                 BlockMove((Ptr) &tempUserData, (Ptr) &DontGetMoreZones, 1); /* the highbyte will be nonzero if its the last packet of zones */
  391.                 BlockMove((Ptr)&tempUserData + 2, (Ptr) &NumZonesGot, 2);
  392.  
  393.                 addToUnpackedBuffer(myZoneBDS.buffPtr, returnBuffer, NumZonesGot, totalZones);    
  394.                 
  395.                 totalZones += NumZonesGot;
  396.                 }
  397.             }
  398.         
  399.         SetZoneCells(returnBuffer, totalZones);
  400.  
  401.         DisposPtr(theBufferPtr);
  402.         DisposPtr(returnBuffer);
  403.         }
  404.     
  405. }
  406.     
  407. Boolean zonesPresent() 
  408. {
  409.     short         theBridgeNode = 0;
  410.     short        theBridgeNet = 0;
  411.     short        node;
  412.     OSErr        err;
  413.  
  414.     err = GetNodeAddress(&node, &theBridgeNet);
  415.     /* 
  416.      * On an extended network, this node ID is simply a flag.  Use _GetAppletalkInfo to get the
  417.      * real 24 bit address of the last router heard from.
  418.      */
  419.     theBridgeNode = GetBridgeAddress();
  420.     
  421.     if (theBridgeNet != 0 && theBridgeNode != 0) {
  422.         gTheBridgeAddress.aNet = theBridgeNet;
  423.         gTheBridgeAddress.aNode = theBridgeNode;
  424.         gTheBridgeAddress.aSocket = kBridgeSocket;
  425.         return true;
  426.         }
  427.     else
  428.         return false;
  429. }
  430.  
  431.     
  432. void setItemString(DialogPtr whichDialog, short whichItem, Str255 str)
  433. {
  434.     Rect         r;
  435.     short         kind;
  436.     Handle         h;
  437.     
  438.     GetDItem(whichDialog, whichItem, &kind, &h, &r);
  439.     SetIText(h, str);
  440. }
  441.      
  442.  
  443. void getTheZoneList()
  444. {
  445.     if (zonesPresent()) {
  446.  
  447.         /*
  448.          * if AppleTalk Phase 2 is present (>= v53) then use new call
  449.          */
  450.         if(gHasPhase2)
  451.             doGetZoneListPhs2();
  452.         else
  453.             doGetZoneListPrePh2();
  454.         }
  455.     else { 
  456.         /* 
  457.          *    no zones.  inform user of this. 
  458.          */
  459.         tellUserNoZones();
  460.         }
  461. }
  462.  
  463.  
  464. void processListUpdate()
  465. {
  466.     Str255    tempStr, errorStr;
  467.     
  468.     if(gPBLkUP->myMPP.MPPioResult >= noErr) {
  469.         NumToString((long) gPBLkUP->myMPP.NBPnumGotten, tempStr);
  470.         Pstrcat((char *) &tempStr, (char *) "\p items");
  471.     
  472.         SetObjectTypeCells(gBuffPtr, gPBLkUP->myMPP.NBPnumGotten);
  473.         }
  474.     else {
  475.         NumToString((long) gPBLkUP->myMPP.MPPioResult, errorStr);
  476.         tempStr[0] = 0;
  477.         Pstrcat( (char *) &tempStr, (char *) "\pError ID = ");
  478.         Pstrcat((char *) &tempStr, (char *) &errorStr);
  479.         }
  480.     
  481.     gUpdateListFlag = false;
  482.     gLookupFinished = true;
  483.  
  484.     /* nil out text since we're done looking */
  485.     ParamText("\p", "\p", "\p", "\p");        
  486.  
  487.     setItemString(gMyDialog, (short) kObjectCountID, tempStr);
  488.  
  489.     invalidateItem(kProgressID);
  490.     invalidateItem(kObjectCountID);
  491. }
  492.     
  493.  
  494. void myCompletionRoutine()
  495. {    
  496.     saveThatA5();
  497.     
  498.     gUpdateListFlag = true;
  499.     
  500.     restoreThatA5();
  501. }
  502.     
  503. char giveMeItemValue(short whichItem)
  504.  {
  505.     Rect         r;
  506.     short         kind;
  507.     Handle         h;
  508.     Str255        str;
  509.     long         value;
  510.     
  511.     GetDItem(gLookupDialog, whichItem, &kind, &h, &r);
  512.     GetIText(h, str);
  513.     StringToNum(str, &value);
  514.     
  515.     if(value>255) {
  516.         value = 255L;
  517.         SetIText(h, "\p255");
  518.         }
  519.     else if(value<0) {
  520.         value = 0L;
  521.         SetIText(h, "\p0");
  522.         }
  523.     return (short)value;
  524. }
  525.      
  526. void giveMeItemString(short whichItem, Str255 str)
  527. {
  528.     Rect         r;
  529.     short         kind;
  530.     Handle         h;
  531.     
  532.     GetDItem(gLookupDialog, whichItem, &kind, &h, &r);
  533.     GetIText(h, str);
  534. }
  535.      
  536. void getTypesNamesInZone(char * NBPZone)
  537. {
  538.     OSErr                 resultCode;
  539.     Str255             NBPObject, NBPType;
  540.     Str255                tempText;
  541.     Str32                noZoneName = "\pNo zones <*>.";
  542.     Str32                localZone = "\pthe local zone";
  543.     Boolean                localFlag = false;
  544.     
  545.     /*myVBLSpinInstall();*/
  546.     
  547.     /*
  548.      * Check whether there are no zones in the zone list
  549.      */
  550.     if (PStrComp((char *)noZoneName, gNameGlob)) {
  551.         gNameGlob[0] = 1;
  552.         gNameGlob[1] = '=';
  553.         localFlag = true;
  554.     }
  555.     
  556.     BlockMove(NBPZone, &gNameGlob[0], 33L);
  557.  
  558.     /* 
  559.      *    oh dang... there may be an NBPLookup already pending.  Kill It first. 
  560.      */
  561.     killLookups();
  562.     
  563.     giveMeItemString(kObjectItem, NBPObject);
  564.     giveMeItemString(kTypeItem, NBPType);
  565.     NBPSetEntity((Ptr)&gLookupNTE.nt.entityData[0], (Ptr)NBPObject, (Ptr)NBPType, (Ptr)NBPZone);
  566.  
  567.     gPBLkUP->myA5 = *(long *)(CurrentA5);    /* get the Current A5 */
  568.  
  569.     gLookupFinished = false;
  570.  
  571.     gPBLkUP->myMPP.MPPioCompletion = (ProcPtr) myCompletionRoutine;
  572.     gPBLkUP->myMPP.NBPinterval = giveMeItemValue(kIntervalItem);
  573.     gPBLkUP->myMPP.NBPcount = giveMeItemValue(kCountItem);
  574.     gPBLkUP->myMPP.NBPentityPtr = (Ptr)&gLookupNTE.nt.entityData;
  575.     gPBLkUP->myMPP.NBPretBuffSize =  30000L;
  576.     gPBLkUP->myMPP.NBPretBuffPtr = (Ptr) gBuffPtr;
  577.     gPBLkUP->myMPP.NBPmaxToGet =  300;        /* should be plenty */
  578.  
  579.     resultCode = PLookupName((MPPParamBlock *) &gPBLkUP->myMPP, true);        
  580.     
  581.     /* 
  582.      * inform the user of what we are doing 
  583.      *     and zero out current entity count.
  584.      */
  585.     tempText[0] = 0;
  586.     if (localFlag)
  587.         Pstrcat((char *) &tempText, (char *) localZone);
  588.     else
  589.         Pstrcat((char *) &tempText, (char *) NBPZone);
  590.         
  591.     Pstrcat((char *) &tempText, (char *) "\p…");
  592.     ParamText("\p", "\p", "\plooking in:", tempText);        
  593.  
  594.     tempText[0] = 0;
  595.     setItemString(gMyDialog, (short) kObjectCountID, tempText);
  596.  
  597.     invalidateItem(kProgressID);
  598.     invalidateItem(kObjectCountID);
  599. }
  600.  
  601.  
  602. /* 
  603.  *    GetMyZone function 
  604.  */
  605. void doGetMyZonePhs2()
  606. {
  607.     XCallParam    xpb;
  608.     OSErr        resultCode;
  609.     char        myZoneNameBuffer[33];
  610.     short        refNum;
  611.     
  612.     resultCode = OpenDriver("\p.XPP", &refNum);
  613.  
  614.     xpb.ioRefNum = refNum;
  615.     xpb.csCode = xCall;
  616.     xpb.xppSubCode = zipGetMyZone;
  617.     xpb.zipBuffPtr = (Ptr) &myZoneNameBuffer;
  618.     xpb.zipInfoField[0] = 0;    /* ALWAYS 0 */
  619.     resultCode = PBControl((ParmBlkPtr) &xpb, false);
  620. }
  621.  
  622. void doGetLocalZonesPhs2()
  623. {
  624.     XCallParam    xpb;
  625.     OSErr        resultCode = 0;
  626.     Ptr            returnBuffer, theBufferPtr;
  627.     short        refNum;
  628.     short        totalZones = 0;
  629.     
  630.     resultCode = OpenDriver("\p.XPP", &refNum);
  631.  
  632.     returnBuffer = NewPtr(33L*300L); /* size of maxstring size * 300 zones */
  633.     
  634.     theBufferPtr = NewPtr(578); /* size of BDS */
  635.     if(MemError()==noErr) {
  636.  
  637.         xpb.zipInfoField[0] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  638.         xpb.zipLastFlag = 0;
  639.  
  640.         xpb.ioRefNum = refNum;
  641.         xpb.csCode = xCall;
  642.         xpb.xppSubCode = zipGetLocalZones;
  643.         xpb.xppTimeout = 3;
  644.         xpb.xppRetry = 4;
  645.         xpb.zipBuffPtr = (Ptr) theBufferPtr;
  646.  
  647.         while(xpb.zipLastFlag == 0 && resultCode == 0) {
  648.  
  649.             resultCode = PBControl((ParmBlkPtr) &xpb, false);
  650.  
  651.             if(resultCode == noErr) {            
  652.                 addToUnpackedBuffer(theBufferPtr, returnBuffer, xpb.zipNumZones, totalZones);            
  653.                 totalZones += xpb.zipNumZones;
  654.                 }
  655.             }
  656.         
  657.         if(resultCode == noErr)     
  658.             SetZoneCells(returnBuffer, totalZones);
  659.  
  660.         DisposPtr(theBufferPtr);
  661.         DisposPtr(returnBuffer);
  662.         }
  663. }
  664.  
  665. /*
  666.  *    When AppleTalk Phase 2 is present, things go a bit easier.
  667.  */
  668. void doGetZoneListPhs2()
  669. {
  670.     XCallParam    xpb;
  671.     OSErr        resultCode = 0;
  672.     Ptr            returnBuffer, theBufferPtr;
  673.     short        refNum;
  674.     short        totalZones = 0;
  675.         
  676.     resultCode = OpenDriver("\p.XPP", &refNum);
  677.  
  678.     returnBuffer = NewPtr(33*300); /* size of maxstring size * 300 zones */
  679.     
  680.     theBufferPtr = NewPtr(578); /* size of BDS */
  681.     
  682.     if(MemError()==noErr) {
  683.         xpb.zipInfoField[0] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  684.         xpb.zipInfoField[1] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  685.         xpb.zipLastFlag = 0;
  686.         
  687.         xpb.ioRefNum = refNum;
  688.         xpb.csCode = xCall;
  689.         xpb.xppSubCode = zipGetZoneList;
  690.         xpb.xppTimeout = 3;
  691.         xpb.xppRetry = 4;
  692.         xpb.zipBuffPtr = (Ptr) theBufferPtr;
  693.  
  694.         while(xpb.zipLastFlag == 0 && resultCode == 0) {
  695.             resultCode = PBControl((ParmBlkPtr) &xpb, false);
  696.  
  697.             if(resultCode == noErr) {            
  698.                 addToUnpackedBuffer(theBufferPtr, returnBuffer, xpb.zipNumZones, totalZones);            
  699.                 totalZones += xpb.zipNumZones;
  700.                 }
  701.             }
  702.         /*
  703.          *    If all went well, add zone names to our list.
  704.          */
  705.          if(resultCode == noErr)     
  706.             SetZoneCells(returnBuffer, totalZones);
  707.  
  708.         /*
  709.          *    Dispose of memory we allocated.
  710.          */
  711.         DisposPtr(theBufferPtr);
  712.         DisposPtr(returnBuffer);
  713.         }
  714. }
  715.  
  716.     
  717.  
  718. #define kEchoType    4
  719.  
  720. void setupEchoDialog(DialogPtr echoDialog, myNetworkEntity *myEnt)
  721. {
  722.     short            kind;
  723.     Handle            h;
  724.     Rect            r;
  725.     Str32            noZoneName = "\pNo zones <*>.";
  726.     Str32            localZone = "\plocal zone";
  727.     Boolean            localFlag = false;
  728.     
  729.     extern pascal void aboutDialogOKFrame();
  730.     
  731.     GetDItem(echoDialog, 10, &kind, &h, &r);
  732.     SetIText(h, myEnt->object);
  733.  
  734.     GetDItem(echoDialog, 11, &kind, &h, &r);
  735.     SetIText(h, myEnt->type);
  736.  
  737.     GetDItem(echoDialog, 12, &kind, &h, &r);
  738.     if (PStrComp((char *)noZoneName, gNameGlob)) 
  739.         SetIText(h, localZone);
  740.     else
  741.         SetIText(h, gNameGlob);
  742.  
  743.     /* 
  744.      *    set up the userItem proc for the "OK" button outline 
  745.      */
  746.     GetDItem(echoDialog, 13, &kind, &h, &r);
  747.     SetDItem(echoDialog, 13, userItem, (Handle) aboutDialogOKFrame, &r);
  748. }
  749.  
  750.  
  751. void doEcho(myNetworkEntity    *myEnt)
  752. {
  753.     MPPParamBlock     myMPP;
  754.     OSErr            err;
  755.     Boolean            gotEcho = false;
  756.     WDSElement        myWDS[3];    /* minimum of 3 WDS elements in a Write Data Structure */
  757.     Ptr                gHdrPtr;
  758.     Ptr                myBuffer;
  759.     long            myTicks, myWaitTicks, startTicks, stopTicks;
  760.     unsigned char    myHops;
  761.     DialogPtr        echoDialog;
  762.     Str255            str;
  763.     short            kind;
  764.     Handle            h;
  765.     Rect            r;
  766.     short            itemHit;
  767.     AddrBlock         destAddress;
  768.     long            tempL;
  769.     GrafPtr            savedPort;
  770.     QHdr            freeQ, usedQ;
  771.     PacketBuffer    buffers[kNumBuffers];
  772.     PacketPtr        bufPtr;
  773.     short            i;
  774.         
  775.     GetPort(&savedPort);
  776.     
  777. MYVBLSPININSTALL();
  778.     
  779. #ifdef THINK_C
  780.     StringToNum((void *) myEnt->net, (long *) &tempL);
  781.     destAddress.aNet = (short) tempL;
  782.     StringToNum((void *) myEnt->node, (long *) &tempL);
  783.     destAddress.aNode = (short) tempL;
  784.     StringToNum((void *) myEnt->socket, (long *) &tempL);
  785. #else
  786.     StringToNum((Str255) myEnt->net, (long *) &tempL);
  787.     destAddress.aNet = tempL;
  788.     StringToNum((Str255) myEnt->node, (long *) &tempL);
  789.     destAddress.aNode = tempL;
  790.     StringToNum((Str255) myEnt->socket, (long *) &tempL);
  791. #endif
  792.     destAddress.aSocket = tempL;
  793.  
  794.     echoDialog = GetNewDialog(131, 0L, (WindowPtr) -1L);
  795.     SetPort(echoDialog);
  796.     
  797.     TextFont(geneva);
  798.     TextSize(9);
  799.     
  800.     setupEchoDialog(echoDialog, myEnt);
  801.     
  802.     /* set up the free and used queues */
  803.     freeQ.qFlags = 0;
  804.     freeQ.qHead = nil;
  805.     freeQ.qTail = nil;
  806.     
  807.     usedQ.qFlags = 0;
  808.     usedQ.qHead = nil;
  809.     usedQ.qTail = nil;
  810.     
  811.     for (i=0; i<kNumBuffers; i++, freeQ.qFlags ++)
  812.         Enqueue((QElemPtr)&buffers[i], &freeQ);
  813.     
  814.     err = SL_INITSKTLISTENER(&freeQ, &usedQ);
  815.     if (err == noErr) {
  816.     
  817.         myMPP.DDPlistener = (Ptr) SL_THELISTENER;
  818.     
  819.         myMPP.DDPsocket = 0;
  820.         err = POpenSkt(&myMPP, false);
  821.         
  822.         gHdrPtr = NewPtr(17);                 /* max header size */
  823.         
  824.         destAddress.aSocket = 4;             /* Echoer socket */
  825.         myBuffer = NewPtr(ddpMaxData);
  826.         *myBuffer = 1;                        /* tell their Echoer we want a reply with a 1 in the first byte */
  827.         
  828.         BuildDDPwds((Ptr) &myWDS, gHdrPtr, myBuffer, destAddress, kEchoType, ddpMaxData);
  829.         
  830.         myMPP.DDPchecksumFlag = true;
  831.         myMPP.DDPwdsPointer = (Ptr) &myWDS;
  832.         
  833.         startTicks = TickCount();            /* start the timer! */
  834.         
  835.         err = PWriteDDP(&myMPP, false);
  836.     
  837.         myWaitTicks = TickCount() + 600L;    /* wait 10 seconds for reply */
  838.         
  839.         while(myWaitTicks > TickCount() && !usedQ.qHead)  {}
  840.         
  841.         if(usedQ.qHead) {
  842.             bufPtr = (PacketPtr)usedQ.qHead;    /* get the packet ptr */
  843.                             /* we could check the DDP type in the buffer_type field
  844.                              * but we leave it as an exercise to the reader.  
  845.                              * Note that the way the usedQ is structured so that 
  846.                              * we could check whether the packet is for us, or for 
  847.                              * some other process which utilizes the same listener.  
  848.                              * In the next step we dequeue the packet so that it 
  849.                              * doesn't get overwritten */
  850.             if (Dequeue((QElemPtr)usedQ.qHead, &usedQ) == noErr) {
  851.                 stopTicks = bufPtr->buffer_Ticks;
  852.                 myTicks = stopTicks - startTicks;
  853.         
  854.                 GetDItem(echoDialog, 4, &kind, &h, &r);
  855.                 myHops = bufPtr->buffer_Hops;
  856.                 NumToString((long) myHops, (void *) &str);
  857.                 SetIText(h, str);
  858.             
  859.                 GetDItem(echoDialog, 5, &kind, &h, &r);
  860.                 NumToString(myTicks, (void *) &str);
  861.                 SetIText(h, str);
  862.                                         /* requeue the packet buffer for use. */
  863.                 Enqueue((QElemPtr)bufPtr, &freeQ);
  864.             }
  865.             else {
  866.                 GetDItem(echoDialog, 6, &kind, &h, &r);
  867.                 SetIText(h, "\pWah… packet Dequeue error occured");
  868.             }
  869.         }
  870.         else {
  871.             GetDItem(echoDialog, 6, &kind, &h, &r);
  872.             SetIText(h, "\pWah… no echo reply received!");
  873.         }
  874.         DisposPtr(gHdrPtr);
  875.         DisposPtr(myBuffer);
  876.         err = PCloseSkt(&myMPP, false);    
  877.     }
  878.     else {
  879.         GetDItem(echoDialog, 6, &kind, &h, &r);
  880.         SetIText(h, "\pWah… can't initalize socket listener");
  881.     }
  882.     
  883.     centerDialog((WindowPtr) echoDialog);
  884.     
  885.     STOPANDREMOVESPINNINGCURSOR();
  886.  
  887.     InitCursor();
  888.     ShowWindow(echoDialog);
  889.     
  890.     ModalDialog(0L, &itemHit);
  891.     DisposDialog(echoDialog);
  892.     
  893.     SetPort(savedPort);
  894. }
  895.  
  896. /*
  897.  *    Here's our AppleTalk Transition Queue handler - we just want
  898.  *  to know if the user shuts down AppleTalk, or changes connections
  899.  *  and do the right thing like deregister our NBP name.
  900.  */
  901.  
  902. long ATalkTransQueue(long selector, myATQEntry *q, void *p)
  903. {
  904.     long                        returnVal = 0; /* return 0 for unrecognized events */
  905.     NameChangePtr                myNameChangePtr;
  906.     TNewCRTransPtr                myTNewCRTransPtr;
  907.       TNetworkTransitionPtr        myTNetworkTransitionPtr;
  908.     NetworkTransitionProcPtr    myNTProcPtr;
  909.     StringPtr                    newNamePtr;
  910.     long                        checkThisNet;
  911.     char                         **t;
  912.     short                        myCableLo, myCableHi;
  913.  
  914.         
  915.     /*
  916.      * This is the dispatch part of the routine. We'll check the selector passed into
  917.      * the task; its location is 4 bytes off the stack (selector).
  918.      */
  919.  
  920.     switch(selector) {
  921.         case ATTransOpen:
  922.             /*
  923.              *  Someone has opened the .MPP driver. Let's initialize ourselves
  924.              */
  925.              
  926.             InitAppleTalkVars();
  927.             break;
  928.             
  929.         case ATTransClose:
  930.             /*
  931.              *  .MPP is going to shut down no matter what we do.  Call Cleanup routine
  932.              */
  933.             closeUpOurAppleTalk();
  934.             break;
  935.             
  936.             
  937.         case ATTransNameChangeTellTask:
  938.             /*
  939.              *  Someone is changing the Flagship name and there is nothing we can do.
  940.              *  The parameter 'p' is a pointer to a Pascal-style string that holds the new
  941.              *  Flagship name. 
  942.                */
  943.             newNamePtr = (StringPtr) p;
  944.  
  945.             /*
  946.              *  You should deregister any previously registered NBP entries under the 
  947.              *  'old' Flagship name. Always return 0.
  948.              */
  949.             break;
  950.             
  951.         case ATTransNameChangeAskTask:
  952.             /*
  953.              *  Someone is messing with the Flagship name. 
  954.              *  With this event, the parameter 'p' actually means something. 'p' is
  955.              *  a pointer to a NameChangeInfo record. The newObjStr field contains the 
  956.              *  new Flagship name. Try to register a new entity using the new Flagship name.
  957.              *  Returning a value of 0 means it's OK to change the Flagship name.
  958.              */
  959.             myNameChangePtr = (NameChangePtr)p;
  960.  
  961.             /*
  962.              *  If the NBPRegister is unsuccessful, return the error. You must also set
  963.              *  p->name pointer with a pointer to a Pascal-style string of the process 
  964.              *  name.
  965.              */
  966.             break;
  967.             
  968.         case ATTransCancelNameChange:
  969.             /*
  970.              *  Just kidding, we didn't really want to change that name after 
  971.              *  all. Remove new NBP entry registered under the ATTransNameChangeAskTask
  972.              *  Transition. In our case,  we'll just fall through. 'p' will be nil. Remember
  973.              *  to return 0. 
  974.              */
  975.             break;
  976.  
  977.         case ATTransCableChange:
  978.             /*
  979.              *  The cable range for the network has changed. The pointer 'p' points
  980.              *  to a structure with the new network range. (TNewCRTransPtr)p->newCableLo
  981.              *  is the lowest value of the new network range. (TNewCRTransPtr)p->newCableHi
  982.              *  is the highest value of the new network range. After handling this event,
  983.              *  always return 0.
  984.              */
  985.             myTNewCRTransPtr = (TNewCRTransPtr)p;
  986.             myCableLo = myTNewCRTransPtr->newCableLo;
  987.             myCableHi = myTNewCRTransPtr->newCableHi;
  988.             break;
  989.  
  990.     } /* end of switch */
  991.     
  992.     /* 
  993.      *    return value in register D0 
  994.      */
  995.     return returnVal;
  996. }
  997.  
  998.  
  999. /*
  1000.  *    This routine doesn't do anything, but was thrown in at not extra cost to you
  1001.  *    the user.
  1002.  */
  1003.  
  1004. /*
  1005. void doGetAppleTalkInfo()
  1006. {
  1007.     getAppleTalkInfoParam    gpb;
  1008.     OSErr                    resultCode;
  1009.     short                    refNum;
  1010.     char                    myZoneNameBuffer[33];
  1011.     
  1012.     Debugger();
  1013.     resultCode = OpenDriver("\p.MPP", &refNum);
  1014.  
  1015.     gpb.ioRefNum = refNum;
  1016.     gpb.csCode = getAppleTalkInfo;
  1017.     gpb.version = 1;
  1018.     gpb.LALength = 0L;
  1019.     gpb.linkAddr = 0L;
  1020.     gpb.zoneName = (Ptr) &myZoneNameBuffer;
  1021.     
  1022.     resultCode = PBControl(&gpb, false);
  1023. }
  1024. */
  1025.  
  1026. /*
  1027. typedef struct
  1028.     {
  1029.     char    cmdByte;
  1030.     char    fpData;
  1031.     char    fpExtra[86];
  1032.     } AFPLoginRec;
  1033.  
  1034. typedef struct
  1035.     {
  1036.     char    cmdByte;
  1037.     char    bitMap;
  1038.     char    volName[27];
  1039.     char    password[8];
  1040.     } cbOpenVolRec;
  1041.  
  1042. typedef struct 
  1043.     {
  1044.     long    srvTime;
  1045.     char    volCount;
  1046.     char    volArray;
  1047.     char    volExtra[64];
  1048.     } ServerRec;
  1049.     
  1050.  
  1051. pascal void    ack()
  1052.     {
  1053.     SysBeep(2);
  1054.     }
  1055. extractAndKill()
  1056. {    
  1057.     ATPParamBlock     killerPB;
  1058.     BDSElement         killerBDS;
  1059.     OSErr             resultCode;
  1060.  
  1061.     XPPParmBlkPtr    xppAccess;
  1062.     XPPParamBlock    *xppGtSrvPrms;
  1063.     AFPLoginRec        theCB, theCBGtSrvPrms;
  1064.     ServerRec        *theServerRec;
  1065.     cbOpenVolRec    cbOpenVol;
  1066.     char            *vers, *auth, *myName, *myPWord;
  1067.     short            index;
  1068.     char            theRB[578];
  1069.     Ptr                a;
  1070.     short            gXPPRef, rbSize;
  1071.     AddrBlock        serverAddress;
  1072.     char            entityData[99];
  1073.     Ptr             gSCBPtr;
  1074.     
  1075.     serverAddress.aNet = 14022;
  1076.     serverAddress.aNode = 41;
  1077.     serverAddress.aSocket = 252;
  1078.     
  1079.     resultCode = OpenXPP(&gXPPRef);
  1080.      xppAccess = (XPPParmBlkPtr)NewPtr(sizeof(XPPParamBlock));
  1081.     xppGtSrvPrms = (XPPParmBlkPtr)NewPtr(sizeof(XPPParamBlock));
  1082.     theServerRec = (ServerRec *)NewPtr(sizeof(ServerRec)*20);
  1083.  
  1084.     gSCBPtr = NewPtr(scbMemSize);
  1085.  
  1086.     theCB.cmdByte = afpLogin;
  1087.  
  1088.     a = &theCB.fpData;
  1089.     
  1090.     index = 0L;
  1091.     vers = "\pAFPVersion 1.1";
  1092.     BlockMove((Ptr)vers, (Ptr)a, vers[0]+1L);
  1093.     index = vers[0]+1L;
  1094.  
  1095.     auth = "\pNo User Authent";
  1096.     BlockMove((Ptr)auth, (Ptr)a+index, (long)auth[0]+1L);
  1097.     index += auth[0]+1L;
  1098.  
  1099.     rbSize = 578;
  1100.     
  1101.     xppAccess->cmdResult = 0;
  1102.     xppAccess->ioRefNum = xppRefNum;     /*its always -41 /
  1103.     xppAccess->XPPaspTimeout = 3;
  1104.     xppAccess->XPPaspRetry = 3;
  1105.     xppAccess->XPPcbSize = (short)2 + index;
  1106.     xppAccess->XPPcbPtr = (Ptr)&theCB;    
  1107.     xppAccess->XPPrbSize = rbSize;
  1108.     xppAccess->XPPrbPtr = (Ptr)&theRB;     /*this is where server info will be place /
  1109.     xppAccess->XPPafpAddrBlock = serverAddress;
  1110.     xppAccess->XPPafpSCBPtr = gSCBPtr;    /* this is where server info will be place /
  1111.     xppAccess->XPPafpAttnRoutine = (Ptr)ack;
  1112.     
  1113.     resultCode = AFPCommand(xppAccess, false);
  1114.  
  1115.     if(xppAccess->cmdResult == noErr ) {
  1116.             theCBGtSrvPrms.cmdByte = afpGetSParms;
  1117.             rbSize = sizeof(ServerRec)*20;
  1118.             
  1119.             xppGtSrvPrms->cmdResult = 0;
  1120.             xppGtSrvPrms->ioRefNum = xppRefNum;    
  1121.             xppGtSrvPrms->XPPsessRefnum = xppAccess->XPPsessRefnum;
  1122.             xppGtSrvPrms->XPPaspTimeout = 5;
  1123.             xppGtSrvPrms->XPPcbSize = 2;
  1124.             xppGtSrvPrms->XPPcbPtr = (Ptr)&theCBGtSrvPrms;
  1125.     
  1126.             xppGtSrvPrms->XPPrbSize = rbSize;
  1127.             xppGtSrvPrms->XPPrbPtr = (Ptr)theServerRec;     /*this is where server info will be place /
  1128.             
  1129.             resultCode = AFPCommand(xppGtSrvPrms, false);
  1130.  
  1131.             cbOpenVol.cmdByte = afpOpenVol;
  1132.             cbOpenVol.bitMap = 511;
  1133.             BlockMove(theServerRec->volExtra, &cbOpenVol.volName[0], 27L);
  1134.             
  1135.             rbSize = sizeof(ServerRec)*20;
  1136.             
  1137.             xppGtSrvPrms->cmdResult = 0;
  1138.             xppGtSrvPrms->ioRefNum = xppRefNum;     
  1139.             xppGtSrvPrms->XPPsessRefnum = xppAccess->XPPsessRefnum;
  1140.             xppGtSrvPrms->XPPaspTimeout = 5;
  1141.             xppGtSrvPrms->XPPcbSize = sizeof(cbOpenVolRec);
  1142.             xppGtSrvPrms->XPPcbPtr = (Ptr)&cbOpenVol;
  1143.     
  1144.             xppGtSrvPrms->XPPrbSize = 30;
  1145.             xppGtSrvPrms->XPPrbPtr = (Ptr)theRB; /*this is where server info will be place /
  1146.             
  1147.             resultCode = AFPCommand(xppGtSrvPrms, false);
  1148.  
  1149.  
  1150.             theCBGtSrvPrms.cmdByte = afpLogout;
  1151.             rbSize = sizeof(ServerRec)*20;
  1152.             
  1153.             xppGtSrvPrms->cmdResult = 0;
  1154.             xppGtSrvPrms->ioRefNum = xppRefNum;    
  1155.             xppGtSrvPrms->XPPsessRefnum = xppAccess->XPPsessRefnum;
  1156.             xppGtSrvPrms->XPPaspTimeout = 5;
  1157.             xppGtSrvPrms->XPPcbSize = 2;
  1158.             xppGtSrvPrms->XPPcbPtr = (Ptr)&theCBGtSrvPrms;
  1159.     
  1160.             xppGtSrvPrms->XPPrbSize = rbSize;
  1161.             xppGtSrvPrms->XPPrbPtr = (Ptr)theServerRec;
  1162.             
  1163.             resultCode = AFPCommand(xppGtSrvPrms, false);
  1164.         }
  1165.     }
  1166.  
  1167. */